package server.util.model;

import java.awt.Component;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import util.Client;

public class ClientTableModel extends AbstractTableModel {

    public static final int //
            COL_VERSION = 0,
            COL_IP_EXTERNAL = 1,
            COL_IP_INTERNAL = 2,
            COL_HOSTNAME = 3,
            COL_USERNAME = 4,
            COL_STATUS = 5,
            COL_OS = 6,
            COL_JAVA = 7;

    private String[] columnNames = {"Version", "External IP", "Internal IP", "Hostname", "Username", "Status", "Operating System", "Java Version"};
    private List<Client> data;
    private JTable table;

    public ClientTableModel(JTable table) {
        super();
        this.table = table;

        data = new ArrayList<>();
    }

    @Override
    public int getRowCount() {
        return data.size();
    }

    @Override
    public int getColumnCount() {
        return columnNames.length;
    }

    @Override
    public Object getValueAt(int row, int col) {
        Client client = data.get(row);

        switch (col) {
            case COL_VERSION:
                return client.version;
            case COL_IP_EXTERNAL:
                return client.ipExternal;
            case COL_IP_INTERNAL:
                return client.ipInternal;
            case COL_HOSTNAME:
                return client.hostname;
            case COL_USERNAME:
                return client.username;
            case COL_STATUS:
                return (client.idling ? "IDLE" : "ACTIVE");
            case COL_OS:
                return client.osName;
            case COL_JAVA:
                return client.javaVersion;
        }

        return "-";
    }

    @Override
    public String getColumnName(int col) {
        return columnNames[col];
    }

    public void addClient(Client client) {
        data.add(client);
        fireDataChanged();
    }

    public void addClients(boolean clear, List<Client> clients) {
        if (clear) {
            clear();
        }

        for (Client client : clients) {
            data.add(client);
        }
        
        fireDataChanged();
    }

    public void clear() {
        data.clear();
    }

    public Client getClientAt(int row) {
        return data.get(row);
    }

    private void fireDataChanged() {
        this.fireTableDataChanged();

        for (int column = 0; column < table.getColumnCount(); column++) {
            TableColumn tableColumn = table.getColumnModel().getColumn(column);
            int preferredWidth = tableColumn.getMinWidth();
            int maxWidth = tableColumn.getMaxWidth();

            for (int row = 0; row < table.getRowCount(); row++) {
                TableCellRenderer cellRenderer = table.getCellRenderer(row, column);
                Component c = table.prepareRenderer(cellRenderer, row, column);
                int width = c.getPreferredSize().width + table.getIntercellSpacing().width;
                preferredWidth = Math.max(preferredWidth, width);

                if (preferredWidth >= maxWidth) {
                    preferredWidth = maxWidth;
                    break;
                }
            }

            tableColumn.setPreferredWidth(preferredWidth);
        }
    }
}
